/**
 * 
 */
package soa.security.mgr.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import soa.security.domain.Region;
import soa.security.exception.OrganizationException;
import soa.security.mgr.service.RegionMgrService;
import soa.security.util.BeanUtils;
import soa.security.util.PinYin4jUtil;

/**
 * @author Cre.Gu
 *
 */
@Service
public class RegionMgrServiceImpl extends BaseMgrServiceImpl implements
		RegionMgrService {
	protected final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(this.getClass());

	@Resource
	private LdapTemplate ldapTemplate;

	@Override
	public void addRegion(String parentDn, Region region)
			throws OrganizationException {
		try {
			validate(region);
			if(StringUtils.isBlank(parentDn))
				parentDn = Region.root().buildDn().toString();
			
			region.setParentDn(parentDn);
			region.setDn(region.buildDn());

			regionDao.create(region);
		} catch (Exception e) {
			wrapException(e);
		}
	}
	
	public void addRegion(String parentDn, Region region,boolean root)
			throws OrganizationException {
		try {
			validate(region);
			if(!root && StringUtils.isBlank(parentDn))
				parentDn = Region.root().buildDn().toString();
			
			region.setParentDn(parentDn);
			region.setDn(region.buildDn());

			regionDao.create(region);
		} catch (Exception e) {
			wrapException(e);
		}
	}

	@Override
	public void updateRegion(String parentDn, Region region)
			throws OrganizationException {
		try {
			validate(region);
			
			if(StringUtils.isBlank(parentDn))
				parentDn = Region.root().buildDn().toString();
			
			region.setParentDn(parentDn);
			region.setDn(region.buildDn());

			regionDao.update(region);
		} catch (Exception e) {
			wrapException(e);
		}
	}

	private void validate(Region d) {
		if (StringUtils.isBlank(d.getDc()))
			d.setDc(PinYin4jUtil.converterToFirstSpell(d.getName()));

		Assert.hasText(d.getDc(), "地区缩写不能为空");
		Assert.hasText(d.getName(), "地区名称不能为空");
		Assert.hasText(d.getCode(), "行政区划编码不能为空");

		BeanUtils.blank2Null(d);
	}

	@Override
	public List<Region> allRegions(String parentDn)
			throws OrganizationException {
		return allRegions(parentDn, (Map<String, Object>) null);
	}

	@Override
	public List<Region> allRegions(String parentDn,
			Map<String, Object> parameters) throws OrganizationException {
		List<Region> results = new ArrayList<Region>();
		try {
			if (StringUtils.isBlank(parentDn))
				parentDn = Region.root().buildDn().toString();

			results = regionDao.allRegions(parentDn, defaultSearchScope,
					parameters);

			for (Region region : results) {
				region.setParent(findByDn(parentDn));
			}

			sortResult(results);
		} catch (Exception e) {
			wrapException(e);
		}
		return results;
	}

	@Override
	public Page<Region> allRegions(String parentDn, PageRequest pageRequest)
			throws OrganizationException {
		try {
			return regionDao.allRegions(parentDn, defaultSearchScope4Ldaptive,
					pageRequest);
		} catch (Exception e) {
			wrapException(e);
		}
		return null;
	}

	@Override
	public Region findByDn(String dn) {
		try {
			if (StringUtils.isBlank(dn))
				return null;
			return regionDao.findByDn(dn);

		} catch (Exception e) {
			printException(e);
			if (log.isDebugEnabled())
				log.debug("错误信息", e);

			return null;
		}
	}

	@Override
	public boolean deleteByDn(String dn) {
		try {
			regionDao.deleteByDn(dn);
			return true;
		} catch (Exception e) {
			printException(e);
			if (log.isDebugEnabled())
				log.debug("错误信息", e);

			return false;
		}
	}

	@Override
	public Region initRoot() {
		Region root = Region.root();

		addRegion(null, root, true);
		return root;
	}

	@Override
	public boolean existCode(String dn, String code) {
		try {
			return regionDao.existCode(code).size() > 0;
		} catch (Exception e) {
			printException(e);
			return true;
		}
	}

	@Override
	public Region existByCode(String code) {
		try {
			List<Region> list = regionDao.existCode(code);
			if (list.size() > 0) {
				return list.get(0);
			}
		} catch (Exception e) {
			printException(e);
		}
		return null;
	}
}
